﻿using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Hosting;
using Newtonsoft.Json;
using PMS.Core.Infrastructure;
using PMS.Core.Utils;

namespace PMS.Data.DbUtils
{
    /// <summary>
    /// Represents the data settings manager
    /// </summary>
    public partial class DataSettingsManager
    {
        #region Methods

        /// <summary>
        /// Load data settings
        /// </summary>
        /// <param name="filePath">File path; pass null to use the default settings file</param>
        /// <param name="reloadSettings">Whether to reload data, if they already loaded</param>
        /// <param name="fileProvider">File provider</param>
        /// <returns>Data settings</returns>
        public static DataSettings LoadSettings(string filePath = null, bool reloadSettings = false, IPMSFileProvider fileProvider = null)
        {
            if (!reloadSettings && Singleton<DataSettings>.Instance != null)
                return Singleton<DataSettings>.Instance;

            fileProvider ??= CommonHelper.DefaultFileProvider;
            filePath ??= fileProvider.MapPath(DataSettingFilePath);

            //check whether file exists
            if (!fileProvider.FileExists(filePath))
                throw new PMSException($"Database configuration file missed: {filePath}");

            var text = fileProvider.ReadAllText(filePath, Encoding.UTF8);
            if (string.IsNullOrEmpty(text))
                return new DataSettings();

            //get data settings from the JSON file
            Dictionary<string, DataSettings> dbEnvSettings = JsonConvert.DeserializeObject<Dictionary<string, DataSettings>>(text);
            var webHostEnvironment = EngineContext.Current.Resolve<IWebHostEnvironment>();
            string envName = webHostEnvironment.IsDevelopment()
                           ? "Development"
                           : "Production";
            foreach (var (key, value) in dbEnvSettings)
            {
                if (key.Equals(envName, StringComparison.InvariantCultureIgnoreCase))
                {
                    value.ConfigEnvName = envName;
                    Singleton<DataSettings>.Instance = value;
                    break;
                }
            }
            
            return Singleton<DataSettings>.Instance;
        }

        /// <summary>
        /// Save data settings to the file
        /// </summary>
        /// <param name="settings">Data settings</param>
        /// <param name="fileProvider">File provider</param>
        public static void SaveSettings(DataSettings settings, IPMSFileProvider fileProvider = null)
        {
            Singleton<DataSettings>.Instance = settings ?? throw new ArgumentNullException(nameof(settings));

            fileProvider ??= CommonHelper.DefaultFileProvider;
            var filePath = fileProvider.MapPath(DataSettingFilePath);

            //create file if not exists
            fileProvider.CreateFile(filePath);

            //save data settings to the file
            var text = JsonConvert.SerializeObject(Singleton<DataSettings>.Instance, Formatting.Indented);
            fileProvider.WriteAllText(filePath, text, Encoding.UTF8);
        }

        #endregion

        #region Properties
        /// <summary>
        /// Gets a path to the file that contains data settings
        /// </summary>
        public static string DataSettingFilePath => "~/App_Data/dataSettings.json";
        /// <summary>
        /// Gets the command execution timeout.
        /// </summary>
        /// <value>
        /// Number of seconds. Negative timeout value means that a default timeout will be used. 0 timeout value corresponds to infinite timeout.
        /// </value>
        public static int SQLCommandTimeout => LoadSettings()?.SQLCommandTimeout ?? -1;

        #endregion
    }

}
